---
layout: default
---
<script src="../js/download.js" type="module"></script>
<script>
    $(document).ready(changeBgText);
</script>
<link class="add-md" rel="dns-prefetch" href="//cdn.mathjax.org" xmlns="http://www.w3.org/1999/html"/>
<link class="add-md" rel="stylesheet" href="../prism.css"/>
<style>
    .toc-container {
        position: fixed;
        left: 80%;
        max-width: 20%;
        max-height: calc(100% - 90px);
        overflow: auto;
        top: calc((100% - 90px) / 2);
        transform: translateY(-50%);
    }

    * {
        max-width: 100%;
    }

    .toc-container ul {
        list-style: none;
        padding-left: 20px;
    }

    .toc-container li {
        margin: 5px 0;
    }
</style>
<div class="toc-container">
    <h1>目录</h1>
    <div id="toc"></div>
</div>
<article class="page">
    <div id="page-header">
        <h1 class="toc-ignore">{{ page.title }}</h1>
        <address class="meta" style="font-size: 12px;">
            创作日期：{{ page.date | date: "%Y年%m月%d日" }}
            <br/>
            创作者：{{ page.author }}
            <br/>
            分类：{{ page.class }}
            <br/>
            注：
            <br/>
            文章所有下载<a href="https://gitcode.com/Leo-hele/download_files/">内容</a>、<a
                href="https://gitee.com/Leo-hele/picGo-image">图片</a>均由<a href="https://gitcode.com">GitCode</a>、<a
                href="https://gitee.com">Gitee</a>托管，中国访问速度较快。如果您在国外，可以在官网下载。
            <br/>
            如果您发现内容有误或需要更新，请在<a href="https://github.com/Leo-hele/Leo-hele.github.io/issues">Github</a>上提交Issue、PR等，或<a
                href="mailto:{{ page.email }}?subject=建议">联系作者</a>，谢谢！
            <br/>
        </address>
        <a download="{{ page.title }}.html" id="download-html">下载html文件</a>
        <script>
            const a = $("#download-html");
            a.attr("href", window.location.href);
        </script>
        <hr/>
    </div>
    <div id="md-file" class="add-md">
        {{ content }}
    </div>
</article>
<script class="add-md">
    {% raw %}
    function addLiquid() {
        const md = $("#md-file");
        let res = md.html();
        res = res.replaceAll("{\\%", "{%");
        res = res.replaceAll("{\\{", "{{");
        md.html(res);
    }
    addLiquid();
    {% endraw %}

    function Query(className) {
        const mdfile = $("#md-file");
        const elements = mdfile.find(className);
        return elements;
    }

    function generateTOC() {
        const headings = Query("h1,h2,h3,h4,h5,h6")
            .filter(heading => ! $(heading).hasClass('toc-ignore'))
            .each((index, cheading) => {
                let heading = $(cheading);
                // 增强ID生成安全性
                let id = heading.text();
                id = `homf${index}-${id}`;
                heading.attr("id", id);
                return heading;
            });

        const tocContainer = $("#toc");
        tocContainer.html('<ul style="padding-left: 0"></ul>');
        let currentLevel = 1;
        let ul = tocContainer.find("ul").first();
        $.each(headings, (index, cheading) => {
            let heading = $(cheading);
            const level = parseInt(heading.prop("tagName").substring(1));
            heading.html(" ".repeat(level - 1) + heading.html()).addClass("no-wrap");
            const id = heading.attr("id");
            // 修复标签闭合逻辑
            if (level > currentLevel) {
                for (let i = currentLevel; i < level; i++) {
                    let newUl = $(document.createElement('ul'));
                    ul.append(newUl);
                    ul = newUl;
                }
            } else if (level < currentLevel) {
                for (let i = currentLevel; i > level; i--) {
                    ul = ul.parent();
                }
            }
            const cpyHeading = $(document.createElement("div"));
            cpyHeading.html(`<span>${heading.html()}</span><hr />`);
            cpyHeading.find("a").removeAttr("href").addClass("toc-link");
            cpyHeading.find("button").removeAttr("onclick");
            cpyHeading.on("click", () => {
                window.location.hash = `#${id}`;
            });
            let li = $(document.createElement("li"));
            ul.append(li.append(cpyHeading));
            currentLevel = level;
            const h$ = $(document.createElement("a"));
            h$.addClass("heading-show").css("display", "none").attr("href", `#${id}`).html("#");
            heading.append(h$);
            console.log(heading.html());
            $(document).ready(() => {
                // const h$ = heading.find(".heading-show");
                heading.on("mouseenter", () => {
                    h$.css("display", "inline");
                });
                heading.on("mouseleave", () => {
                    h$.css("display", "none");
                });
            });
        });

        tocContainer.css("display", "block");
    }

    // 在页面加载完成后生成目录
    window.addEventListener('DOMContentLoaded', generateTOC);

    function loadPrism() {
        const prismScript = $(document.createElement('script'));
        prismScript.attr("src", '../js/prism.min.js');

        prismScript.ready(function () {
            try {
                if (window.Prism === undefined) {
                    throw new Error("Prism未定义");
                }
            } catch (error) {
                console.error("Prism加载失败！", error);
                return;
            }
            console.log("Prism加载成功！");
            // 确保启用行号插件
            Prism.plugins.lineNumbers = true;

            // 注册下载按钮
            Prism.plugins.toolbar.registerButton('download', {
                text: '下载代码',
                onClick: function (env) {
                    downloadCode(env.code, env.language);
                }
            });

            Prism.highlightAll();
        });
        $(document.head).append(prismScript);
    }
    loadPrism();

    function setTag(className, tags) {
        for (const key in tags) {
            const value = tags[key];
            $(className).attr(key, value);
        }
    }

    setTag("pre", {
        "class": "line-numbers",
    });
    setTag("code", {
        "data-prismjs-copy": "复制",
        "data-prismjs-copy-error": "复制失败",
        "data-prismjs-copy-success": "复制成功",
    });
    $("img").each((index, img) => {
        img = $(img);
        if (!img.attr('data-error-handled')) {
            img.attr('data-error-handled', 'true');

            // 创建备用元素
            const fallback = $(document.createElement('div'));
            fallback.addClass("image-fallback");
            fallback.text(`
                    <a href="${img.src}" target="_blank">图片加载失败！查看原图</a>
                `);
            fallback.css("display", "none");

            // 包装图片
            const container = $(document.createElement('div'));
            container.addClass("image-container");
            img.parent().insertBefore(container, img);
            container.append(img);
            container.append(fallback);

            // 添加错误处理
            img.on('error', () => {
                fallback.style.display = 'block';
            });
        }
    });
    MathJax = {
        tex: {
            inlineMath: [['$', '$'], ['\\(', '\\)']]
        },
        options: {
            skipHtmlTags: [            //  HTML tags that won't be searched for math
                'script', 'noscript', 'style', 'textarea', 'pre',
                'code', 'annotation', 'annotation-xml'
            ],
            enableMenu: false,
        }
    };
</script>
<script class="add-md" id="MathJax-script" async
        src="../js/mathjax/es5/tex-chtml.js">
</script>